#include "beaminit.h"
#include <../rapidxml-1.13/rapidxml.hpp>
#include <fstream>
#include <iostream>
#include <vector>
#include <string>
#include <../rapidxml-1.13/rapidxml.hpp>
#include <stdlib.h>
#include <simplysupported.h>
#include <cantilever.h>

using namespace rapidxml;
using namespace std;

BeamInit::BeamInit()
{
}

void BeamInit::StartCalcs()
{
    //Write out the calculations to a text file as well.
    string PathOut = "output.txt";
    ofstream strOut;
    strOut.open (PathOut.c_str());


    //Open the XML file
    //ifstream myfile ("Others/Beams.xml");
    ifstream myfile ("Beams.xml");
    vector<char> buffer((istreambuf_iterator<char>(myfile)), istreambuf_iterator<char>());

    xml_document<> doc;
    xml_node<> * root;

    buffer.push_back('\0');

    //Start reading the XML file
    doc.parse<0>(&buffer[0]);

    root = doc.first_node("Beams");

    //Loop through all of the nodes under the root node <Beams>
    //This will be how ever many beams that we want to analyze
    for(xml_node<> *beam = root->first_node("Beam"); beam; beam = beam->next_sibling())
    {
        cout << "\nThe following beam is going to be processed." << endl;
        cout << "Beam Type: " << beam->first_attribute("type")->value() << endl;
        cout <<  "Beam Length: " << beam->first_attribute("length")->value() << endl;

        strOut << "\nThe following beam is going to be processed." << endl;
        strOut << "Beam Type: " << beam->first_attribute("type")->value() << endl;
        strOut <<  "Beam Length: " << beam->first_attribute("length")->value() << endl;


        std::string BeamType = beam->first_attribute("type")->value();

        Beam NewBeam();

        //Check beam type
        //Choices are SimplySupported or Cantilever
        if(BeamType == "SimplySupported")
        {
            //Output to the screen
            cout << "Right Support Location: " << beam->first_attribute("rightsupport")->value() << endl;
            cout << "Left Support Location: " << beam->first_attribute("leftsupport")->value() << endl;

            //Output to a file for later work
            strOut << "Right Support Location: " << beam->first_attribute("rightsupport")->value() << endl;
            strOut << "Left Support Location: " << beam->first_attribute("leftsupport")->value() << endl;


            int BeamLength = atoi(beam->first_attribute("length")->value());
            int LeftSupport = atoi(beam->first_attribute("leftsupport")->value());
            int RightSupport = atoi(beam->first_attribute("rightsupport")->value());
            SimplySupported simplebeam(BeamLength, LeftSupport, RightSupport);

            cout << "\nThe following loads have been placed on the beam." << endl;
            strOut << "\nThe following loads have been placed on the beam." << endl;

          for(xml_node<> *loads = beam->first_node("Load"); loads; loads = loads->next_sibling())
            {
                cout << "Load Location: " << loads->first_attribute("Location")->value() << endl;
                cout << "Load Value: " << loads->first_attribute("value")->value() << endl;

                strOut << "Load Location: " << loads->first_attribute("Location")->value() << endl;
                strOut << "Load Value: " << loads->first_attribute("value")->value() << endl;


                int Load_Location = atoi(loads->first_attribute("Location")->value());
                int Load_Value = atoi(loads->first_attribute("value")->value());
                simplebeam.AddLoads(Load_Value, Load_Location);
            }

            cout << "\nFor a simply supported beam the following reactions are found to be true." << endl;
            cout << "Reaction 1 (Left Support): " << simplebeam.GetLeftSupportReaction() << endl;
            cout << "Reaction 2 (Right Support): " << simplebeam.GetRightSupportReaction() << endl;

            strOut << "\nFor a simply supported beam the following reactions are found to be true." << endl;
            strOut << "Reaction 1 (Left Support): " << simplebeam.GetLeftSupportReaction() << endl;
            strOut << "Reaction 2 (Right Support): " << simplebeam.GetRightSupportReaction() << endl;
        }
        else if(BeamType == "Cantilever")
        {

            int BeamLength = atoi(beam->first_attribute("length")->value());
            Cantilever cantileverbeam(BeamLength);

          for(xml_node<> *loads = beam->first_node("Load"); loads; loads = loads->next_sibling())
            {
                cout << "Load Location: " << loads->first_attribute("Location")->value() << endl;
                cout << "Load Value: " << loads->first_attribute("value")->value() << endl;

                strOut << "Load Location: " << loads->first_attribute("Location")->value() << endl;
                strOut << "Load Value: " << loads->first_attribute("value")->value() << endl;


                int Load_Location = atoi(loads->first_attribute("Location")->value());
                int Load_Value = atoi(loads->first_attribute("value")->value());
                cantileverbeam.AddLoads(Load_Value, Load_Location);
            }

            //Output screen
            cout << "\nFor a cantilevered beam the following reactions are found to be true." << endl;
            cout << "Beam Reaction: " << cantileverbeam.GetReaction() << endl;
            cout << "Loading Moment: " << cantileverbeam.GetMoment() << endl;

            //Output to file
            strOut << "\nFor a cantilevered beam the following reactions are found to be true." << endl;
            strOut << "Beam Reaction: " << cantileverbeam.GetReaction() << endl;
            strOut << "Loading Moment: " << cantileverbeam.GetMoment() << endl;

        }
    }

        strOut.close();
        WaitEnd();
}

void BeamInit::WaitEnd()
{
    cout << "\nPress ENTER to continue..."   << endl;
    cin.ignore(1);
}

BeamInit::~BeamInit()
{
    //dtor
}
